package com.ruoyi.system.service.impl;

import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysCorp;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.dao.service.BaseAppDAO;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.dao.SysCorpDAO;
import com.ruoyi.system.dao.SysDeptDAO;
import com.ruoyi.system.service.ISysCorpService;
import com.ruoyi.system.service.ISysDeptService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

@Service
public class SysCorpServiceImpl implements ISysCorpService {


    private static final Logger log = LoggerFactory.getLogger(SysCorpServiceImpl.class);

    @Autowired
    private BaseAppDAO baseDAO;

    @Autowired
    private SysCorpDAO corpDAO;

    @Autowired
    private SysDeptDAO deptDAO;

    @Autowired
    private ISysDeptService sysDeptService;


    /**
     * 根据条件查询公司列表
     *
     * @param corp 公司信息
     * @return 公司信息集合信息
     */
    @Override
    public List<SysCorp> selectCorpList(SysCorp corp) {
        return corpDAO.findAll(getSpecification(corp));
    }

    @Override
    public List<SysCorp> selectCorpListTree(SysCorp corp) {
        List<SysCorp> list = corpDAO.findAll(getSpecification(corp));
        return buildCorpTree(list);
    }

    private List<SysCorp> buildCorpTree(List<SysCorp> corps) {
        List<SysCorp> returnvos = new ArrayList<SysCorp>();//要返回的数据，没有父id的数据为第一层级数据
        if (StringUtils.isNotEmpty(corps)) {
            HashMap<String, List<SysCorp>> childrens = new HashMap<String, List<SysCorp>>();//把所有相同父id的数据放在一起
            SysCorp corp = null;
            for (int i = 0; i < corps.size(); i++) {
                corp = corps.get(i);
                if (StringUtils.isEmpty(corp.getPkFathercorp())) {
                    returnvos.add(corp);
                } else {
                    if (!childrens.containsKey(corp.getPkFathercorp())) {
                        childrens.put(corp.getPkFathercorp(), new ArrayList<SysCorp>());
                    }
                    childrens.get(corp.getPkFathercorp()).add(corp);
                }
            }

            if (StringUtils.isNotEmpty(childrens)) {
                findDomainChildens(returnvos, childrens);
            }
        }
        return returnvos;
    }

    private void findDomainChildens(List<SysCorp> corps, HashMap<String, List<SysCorp>> childrens) {
        if (StringUtils.isNotEmpty(corps) && StringUtils.isNotEmpty(childrens)) {
            for (SysCorp corp : corps) {
                if (childrens.containsKey(corp.getPkCorp())) {
                    corp.setChildren(childrens.get(corp.getPkCorp()));
                    childrens.remove(corp.getPkCorp());
                    findDomainChildens(corp.getChildren(), childrens);
                }
            }
        }
    }

    /**
     * 根据条件分页查询公司列表
     *
     * @param corp     公司信息
     * @param pageinfo
     * @return 公司信息集合信息
     */
    @Override
    public Page<SysCorp> selectCorpList(SysCorp corp, Pageable pageinfo) {
        return corpDAO.findAll(getSpecification(corp), pageinfo);
    }

    private Specification<SysCorp> getSpecification(SysCorp config) {
        return (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (!StringUtils.isNull(config.getPkCorp())) {
                predicateList.add(criteriaBuilder.equal(root.get("pkCorp"), config.getPkCorp()));
            }
            if (!StringUtils.isEmpty(config.getCorpName())) {
                predicateList.add(criteriaBuilder.like(root.get("corpName"), "%" + config.getCorpName() + "%"));
            }
            if (!StringUtils.isNull(config.getEnablestate())) {
                predicateList.add(criteriaBuilder.equal(root.get("enablestate"), config.getEnablestate()));
            }

            if (!StringUtils.isNull(config.getPhone())) {
                predicateList.add(criteriaBuilder.equal(root.get("phone"), config.getPhone()));
            }

            if (!StringUtils.isNull(config.getPkFathercorp())) {
                predicateList.add(criteriaBuilder.equal(root.get("pkFathercorp"), config.getPkFathercorp()));
            }

            if (!StringUtils.isNull(config.getParams().get("beginTime"))) {
                predicateList.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime"), (String) config.getParams().get("beginTime")));
            }

            if (!StringUtils.isNull(config.getParams().get("endTime"))) {
                predicateList.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime"), (String) config.getParams().get("endTime")));
            }

            Predicate[] p = new Predicate[predicateList.size()];
            return criteriaBuilder.and(predicateList.toArray(p));
        };

    }

    /**
     * 通过公司名查询公司
     *
     * @param corpName 公司名
     * @return 公司对象信息
     */
    @Override
    public SysCorp selectCorpByCorpName(String corpName) {

        return corpDAO.findTop1ByCorpName(corpName);
    }

    /**
     * 通过公司ID查询公司
     *
     * @param corpId 公司ID
     * @return 公司对象信息
     */
    @Override
    public SysCorp selectCorpById(String corpId) {

        return corpDAO.findById(corpId).orElse(null);
    }

    /**
     * 校验公司名称是否唯一
     *
     * @param corpName 公司名称
     * @return 结果
     */
    @Override
    public String checkCorpNameUnique(String corpId, String corpName) {
        if (StringUtils.isEmpty(corpId)) {//新增时校验
            SysCorp corp = corpDAO.findTop1ByCorpName(corpName);
            if (corp != null) {
                return UserConstants.NOT_UNIQUE;
            } else {
                return UserConstants.UNIQUE;
            }
        } else {//修改时校验逻辑
            List<SysCorp> corps = corpDAO.findByCorpName(corpName);
            for (SysCorp corp : corps) {
                if (!corp.getPkCorp().equals(corpId)) {
                    return UserConstants.NOT_UNIQUE;
                }
            }
            return UserConstants.UNIQUE;
        }
    }

    /**
     * 校验公司编码是否唯一
     *
     * @param corpId   公司ID
     * @param corpCode
     * @return 结果
     */
    @Override
    public String checkCorpCodeUnique(String corpId, String corpCode) {
        if (StringUtils.isEmpty(corpId)) {//新增时校验
            SysCorp corp = corpDAO.findTop1ByCorpCode(corpCode);
            if (corp != null) {
                return UserConstants.NOT_UNIQUE;
            } else {
                return UserConstants.UNIQUE;
            }
        } else {//修改时校验逻辑
            List<SysCorp> corps = corpDAO.findByCorpCode(corpCode);
            for (SysCorp corp : corps) {
                if (!corp.getPkCorp().equals(corpId)) {
                    return UserConstants.NOT_UNIQUE;
                }
            }
            return UserConstants.UNIQUE;
        }
    }

    /**
     * 校验公司是否有下级公司（只查询启用的下级公司）
     *
     * @param corpId
     * @return
     */
    @Override
    public boolean checkCorpIshaiChildren(String corpId) {
        SysCorp querypara = new SysCorp();
        querypara.setPkFathercorp(corpId);
        querypara.setEnablestate(UserConstants.NORMAL);
        List<SysCorp> re = this.selectCorpList(querypara);
        return re != null && re.size() > 0;
    }

    /**
     * 新增公司信息
     *
     * @param corp 公司信息
     * @return 结果
     */
    @Override
    public SysCorp insertCorp(SysCorp corp) {
        return corpDAO.save(corp);
    }

    /**
     * 修改公司信息
     *
     * @param corp 公司信息
     * @return 结果
     */
    @Override
    public SysCorp updateCorp(SysCorp corp) {
        return corpDAO.save(corp);
    }

    /**
     * 修改公司状态
     *
     * @param corp 公司信息
     * @return 结果
     */
    @Override
    public SysCorp updateCorpStatus(SysCorp corp) {
        corpDAO.updateCorpEnableState(corp.getPkCorp(), corp.getEnablestate());
        return corpDAO.findById(corp.getPkCorp()).orElse(null);
    }

    /**
     * 通过公司ID删除公司
     *
     * @param corpId 公司ID
     * @return 结果
     */
    @Override
    public int deleteCorpById(String corpId) {
        corpDAO.deleteById(corpId);
        return 1;
    }

    /**
     * 批量删除公司信息
     *
     * @param corpIds 需要删除的公司ID
     * @return 结果
     */
    @Override
    public int deleteCorpByIds(String[] corpIds) {
        corpDAO.deleteAllByIdInBatch(Arrays.asList(corpIds));
        return 1;
    }

    /**
     * 导入公司数据
     *
     * @param corpList        公司数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @param operName        操作公司
     * @return 结果
     */
    @Override
    public String importCorp(List<SysCorp> corpList, Boolean isUpdateSupport, String operName) {
        return null;
    }

    /**
     * 查询所有公司和部门的树集合
     *
     * @return
     */
    @Override
    public List<HashMap> seletAllCorpDeptTree() {
        List<SysCorp> corps = corpDAO.findAll();
        List<SysDept> depts = deptDAO.findAll();

        List<HashMap> lists = new ArrayList<>();
        HashMap<String, String> item = null;
        if (StringUtils.isNotEmpty(corps)) {
            lists = ToCorpTreeOptions(corps);
        }
        if (StringUtils.isNotEmpty(depts)) {
            List<HashMap> deptlists = ToDeptTreeOptions(depts);
            CorpAddDept(lists, deptlists);
        }
        return lists;
    }

    /**
     * 根据用户id查询有权限的公司数据
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysCorp> selectRoleCorpByUserId(String userId) {
        return corpDAO.selectRoleCorpByUserId(userId);
    }

    /**
     * 构造组织树结构
     * @param corps
     * @return
     */
    private List<HashMap> ToCorpTreeOptions(List<SysCorp> corps) {
        List<HashMap> returnvos = new ArrayList<HashMap>();//要返回的数据，没有父id的数据为第一层级数据
        HashMap<String, Object> item = null;
        if (StringUtils.isNotEmpty(corps)) {
            HashMap<String, List<HashMap>> childrens = new HashMap<String, List<HashMap>>();//把所有相同父id的数据放在一起
            SysCorp corp = null;
            for (int i = 0; i < corps.size(); i++) {
                corp = corps.get(i);
                item = new HashMap<String, Object>();
                item.put("key", corp.getPkCorp());
                item.put("title", corp.getCorpName());
                item.put("orgType", "C");
                item.put("pkFather", corp.getPkFathercorp());

                if (StringUtils.isEmpty(corp.getPkFathercorp())) {//没有父id的数据为第一层级数据
                    returnvos.add(item);
                } else {
                    if (!childrens.containsKey(corp.getPkFathercorp())) {
                        childrens.put(corp.getPkFathercorp(), new ArrayList<HashMap>());
                    }
                    childrens.get(corp.getPkFathercorp()).add(item);
                }
            }

            if (StringUtils.isNotEmpty(childrens)) {
                findChildens(returnvos, childrens);
            }
        }
        return returnvos;
    }

    private void findChildens(List<HashMap> lists, HashMap<String, List<HashMap>> childrens) {
        if (StringUtils.isNotEmpty(lists) && StringUtils.isNotEmpty(childrens)) {
            for (HashMap list : lists) {
                if (childrens.containsKey(list.get("key"))) {
                    list.put("children",childrens.get(list.get("key")));
                    childrens.remove(list.get("key"));
                    findChildens((List<HashMap>) list.get("children"), childrens);
                }
            }
        }
    }

    /**
     * 构造部门树结构
     * @param depts
     * @return
     */
    private List<HashMap> ToDeptTreeOptions(List<SysDept> depts) {
        List<HashMap> returnvos = new ArrayList<HashMap>();//要返回的数据，没有父id的数据为第一层级数据
        HashMap<String, Object> item = null;
        if (StringUtils.isNotEmpty(depts)) {
            HashMap<String, List<HashMap>> childrens = new HashMap<String, List<HashMap>>();//把所有相同父id的数据放在一起
            SysDept dept = null;
            for (int i = 0; i < depts.size(); i++) {
                dept = depts.get(i);
                item = new HashMap<String, Object>();
                item.put("pkCorp", dept.getPkCorp());
                item.put("key", dept.getDeptId());
                item.put("title", dept.getDeptName());
                item.put("orgType", "D");
                item.put("pkFather", dept.getParentId());

                if (StringUtils.isEmpty(dept.getParentId())) {//没有父id的数据为第一层级数据
                    returnvos.add(item);
                } else {
                    if (!childrens.containsKey(dept.getParentId())) {
                        childrens.put(dept.getParentId(), new ArrayList<HashMap>());
                    }
                    childrens.get(dept.getParentId()).add(item);
                }
            }

            if (StringUtils.isNotEmpty(childrens)) {
                findChildens(returnvos, childrens);
            }
        }
        return returnvos;
    }

    /**
     * 将公司和部门树组合成一棵树
     * @param corps
     * @param depts
     */
    private void CorpAddDept(List<HashMap> corps, List<HashMap> depts) {
        String pkCorp = null;
        for (int i = 0; i < depts.size(); i++) {
            pkCorp = (String) depts.get(i).get("pkCorp");
            for (int j = 0; j < corps.size(); j++) {
                if (corps.get(j).get("key").equals(pkCorp)) {
                    List children = null;
                    if (corps.get(j).containsKey("children")) {
                        children = (List) corps.get(j).get("children");
                    } else {
                        children = new ArrayList<>();
                        corps.get(j).put("children", children);
                    }
                    children.add(depts.get(i));
                }
            }
        }
    }
}
